package com.java.inner_class;

/**
 * 内部类
 */
public class OuterClass {
    private String privateNameSpecific = "外部类特有私有成员";
    public String publicNameSpecific = "外部类特有公共成员";
    static String staticNameSpecific = "外部类特有静态成员";
    
    // 静态内部类：静态内部类的生命周期随类，静态内部类只能直接访问外部类的静态成员且重名时优先访问内部类成员，但外部类想要访问静态内部类成员时需要创建对象或通过类名访问
    static class InnerStatic {
        private String privateName = "静态内部类私有成员";
        public String publicName = "静态内部类公共成员";
        static String staticName = "静态内部类静态成员";
        
        public void func() {
            System.out.println(privateName); // 静态内部类私有成员
            System.out.println(publicName); // 静态内部类公共成员
            System.out.println(staticName); // 静态内部类静态成员
            
            // 无法从 static 上下文引用非 static 字段
            // System.out.println(privateNameSpecific);
            // System.out.println(publicNameSpecific);
            System.out.println(staticNameSpecific); // 外部类特有静态成员
        }
    }
    
    // 成员内部类：成员内部类中不能定义静态成员，成员内部类可直接访问外部类包含私有成员的所有成员且重名时优先访问内部类成员，但外部类想要访问成员内部类成员时需要创建对象
    class InnerMember {
        private String privateName = "成员内部类私有成员";
        public String publicName = "成员内部类公共成员";
        
        // 修饰符 static 仅允许在常量变量声明中使用
        // static String staticName = "成员内部类静态成员";
        
        public void func() {
            System.out.println(privateName); // 静态内部类私有成员
            System.out.println(publicName); // 静态内部类公共成员
            
            System.out.println(privateNameSpecific); // 外部类特有私有成员
            System.out.println(publicNameSpecific); // 外部类特有公共成员
            System.out.println(staticNameSpecific); // 外部类特有静态成员
        }
    }
    
    public void func() {
        String funcName = "方法内部的局部变量";
        
        // 局部内部类：局部内部类类定义时不能使用修饰符，局部内部类可直接访问外部类包含私有成员的所有成员和方法内的局部变量且重名时优先访问内部类成员，外部类不能访问局部内部类
        class InnerScoped {
            private String privateName = "局部内部类私有成员";
            public String publicName = "局部内部类公共成员";
            
            // 修饰符 static 仅允许在常量变量声明中使用
            // static String staticName = "局部内部类静态成员";
            
            public void func() {
                System.out.println(privateName); // 局部内部类私有成员
                System.out.println(publicName); // 局部内部类公共成员
                
                System.out.println(funcName); // 方法内部的局部变量
                
                System.out.println(privateNameSpecific); // 外部类特有私有成员
                System.out.println(publicNameSpecific); // 外部类特有公共成员
                System.out.println(staticNameSpecific); // 外部类特有静态成员
            }
        }
        
        InnerScoped innerScoped = new InnerScoped();
        System.out.println(innerScoped.privateName); // 局部内部类私有成员
        System.out.println(innerScoped.publicName); // 局部内部类公共成员
        innerScoped.func();
    }
}
